from typing import Dict, List, Optional
import pandas as pd
import numpy as np
from datetime import datetime
import pandas_ta as ta
from config.settings import AnalysisConfig, EXCHANGES

'''市场分析器'''
class MarketAnalyzer:
    def __init__(self, technical_indicators, ml_predictor=None):
        """
        初始化市场分析器
        
        Args:
            technical_indicators: 技术指标计算器实例
            ml_predictor: 机器学习预测器实例 (可选)
        """
        self.technical_indicators = technical_indicators
        self.ml_predictor = ml_predictor
        self.exchanges = EXCHANGES
        self.market_data = {}  # 市场数据缓存
        self.indicators = {}   # 技术指标缓存
        
    def update_market_data(self, exchange: str, symbol: str, timeframe: str):
        """更新市场数据"""
        # 获取最新市场数据
        # 这里需要实现具体的数据获取逻辑
        pass
        
    def analyze_price_action(self, symbol: str) -> Dict:
        """价格行为分析"""
        signals = {}
        
        for exchange in self.exchanges:
            df = self.market_data.get((exchange, symbol))
            if df is None:
                continue
                
            # 计算技术指标
            df['rsi'] = ta.rsi(df['close'])
            df['macd'] = ta.macd(df['close'])
            df['bbands'] = ta.bbands(df['close'])
            
            # 价格突破分析
            df['price_change'] = df['close'].pct_change()
            df['volatility'] = df['price_change'].rolling(14).std()
            
            # 生成交易信号
            signals[exchange] = {
                'rsi': df['rsi'].iloc[-1],
                'macd': df['macd'].iloc[-1],
                'volatility': df['volatility'].iloc[-1],
                'price_change': df['price_change'].iloc[-1]
            }
            
        return signals
        
    def analyze_volume_profile(self, symbol: str) -> Dict:
        """成交量分析"""
        volume_signals = {}
        
        for exchange in self.exchanges:
            df = self.market_data.get((exchange, symbol))
            if df is None:
                continue
                
            # 计算成交量指标
            df['volume_ma'] = df['volume'].rolling(20).mean()
            df['volume_std'] = df['volume'].rolling(20).std()
            
            # 检测异常成交量
            volume_signals[exchange] = {
                'volume_ratio': df['volume'].iloc[-1] / df['volume_ma'].iloc[-1],
                'volume_zscore': (df['volume'].iloc[-1] - df['volume_ma'].iloc[-1]) / df['volume_std'].iloc[-1]
            }
            
        return volume_signals
        
    def analyze_market_depth(self, symbol: str) -> Dict:
        """市场深度分析"""
        depth_signals = {}
        
        for exchange in self.exchanges:
            # 获取订单簿数据
            # 分析买卖压力
            # 计算市场深度指标
            pass
            
        return depth_signals
        
    def calculate_correlation(self, symbol: str) -> float:
        """计算交易所间的价格相关性"""
        prices = {}
        
        # 收集各交易所的价格数据
        for exchange in self.exchanges:
            df = self.market_data.get((exchange, symbol))
            if df is not None:
                prices[exchange] = df['close']
                
        # 计算相关性矩阵
        if len(prices) > 1:
            price_df = pd.DataFrame(prices)
            correlation_matrix = price_df.corr()
            
            # 返回平均相关性
            return correlation_matrix.mean().mean()
            
        return 1.0
        
    def generate_trading_signal(self, symbol: str) -> Dict:
        """生成综合交易信号"""
        # 获取各维度分析结果
        price_signals = self.analyze_price_action(symbol)
        volume_signals = self.analyze_volume_profile(symbol)
        correlation = self.calculate_correlation(symbol)
        
        # 综合分析结果
        combined_signal = {
            'price_signals': price_signals,
            'volume_signals': volume_signals,
            'correlation': correlation,
            'timestamp': datetime.now()
        }
        
        # 生成交易建议
        if self._evaluate_signals(combined_signal):
            combined_signal['action'] = 'buy'
        elif self._evaluate_exit_signals(combined_signal):
            combined_signal['action'] = 'sell'
        else:
            combined_signal['action'] = 'hold'
            
        return combined_signal
        
    def _evaluate_signals(self, signals: Dict) -> bool:
        """评估是否应该进场"""
        buy_conditions = []
        
        for exchange, price_signal in signals['price_signals'].items():
            # RSI超卖
            if price_signal['rsi'] < 30:
                buy_conditions.append(True)
                
            # MACD金叉
            if price_signal['macd'] > 0:
                buy_conditions.append(True)
                
            # 价格变化超过阈值
            if abs(price_signal['price_change']) > self.config.price_change_threshold:
                buy_conditions.append(True)
                
        # 检查成交量
        for exchange, volume_signal in signals['volume_signals'].items():
            if volume_signal['volume_ratio'] > 1.5:  # 成交量放大
                buy_conditions.append(True)
                
        # 交易所间价格相关性高
        if signals['correlation'] > self.config.correlation_threshold:
            buy_conditions.append(True)
            
        # 综合判断：满足多个条件才发出买入信号
        return len(buy_conditions) >= 3
        
    def _evaluate_exit_signals(self, signals: Dict) -> bool:
        """评估是否应该出场"""
        sell_conditions = []
        
        for exchange, price_signal in signals['price_signals'].items():
            # RSI超买
            if price_signal['rsi'] > 70:
                sell_conditions.append(True)
                
            # MACD死叉
            if price_signal['macd'] < 0:
                sell_conditions.append(True)
                
            # 剧烈价格波动
            if price_signal['volatility'] > self.config.price_change_threshold * 2:
                sell_conditions.append(True)
                
        # 交易所间价格相关性降低
        if signals['correlation'] < self.config.correlation_threshold:
            sell_conditions.append(True)
            
        # 综合判断：满足多个条件才发出卖出信号
        return len(sell_conditions) >= 2

    def analyze_market(self, market_data: pd.DataFrame) -> Dict:
        """
        分析市场数据，整合技术分析和机器学习预测
        
        Args:
            market_data: 市场数据DataFrame (包含OHLCV数据)
            
        Returns:
            包含分析结果的字典
        """
        try:
            print("开始分析市场数据...")
            print("输入数据列:", market_data.columns.tolist())
            
            # 计算技术指标
            tech_data = self.technical_indicators.calculate_all(market_data)
            print("技术指标计算完成, 指标列:", tech_data.columns.tolist())
            
            # 获取最新的技术指标信号
            tech_signals = self.technical_indicators.get_signal_summary(tech_data)
            print("技术信号:", tech_signals)
            
            # 如果启用了ML预测
            ml_signals = {}
            if self.ml_predictor and not tech_data.empty:
                try:
                    ml_signals = self.ml_predictor.predict(tech_data)
                    print("ML预测完成:", ml_signals)
                except Exception as e:
                    print(f"ML预测错误: {str(e)}")
                    ml_signals = {}
            
            # 综合分析结果
            analysis = {
                'technical': tech_signals,
                'ml': ml_signals,
                'data': tech_data
            }
            
            # 生成交易信号
            if self._should_enter_long(analysis):
                analysis['signal'] = 'long'
            elif self._should_enter_short(analysis):
                analysis['signal'] = 'short'
            else:
                analysis['signal'] = 'neutral'
            
            return analysis
            
        except Exception as e:
            print(f"市场分析错误: {str(e)}")
            raise
    
    def _should_enter_long(self, analysis: Dict) -> bool:
        """
        判断是否应该做多
        """
        if 'technical' not in analysis:
            return False
            
        tech = analysis['technical']
        conditions = []
        
        # MACD信号
        if tech.get('macd_trend') == 'bullish':
            conditions.append(True)
        
        # RSI信号
        if tech.get('rsi', 70) < 70:  # RSI未超买
            conditions.append(True)
            
        # ML信号 (如果有)
        if analysis.get('ml', {}).get('prediction') == 'up':
            conditions.append(True)
            
        # 满足大部分条件时返回True
        return len(conditions) >= 2
    
    def _should_enter_short(self, analysis: Dict) -> bool:
        """
        判断是否应该做空
        """
        if 'technical' not in analysis:
            return False
            
        tech = analysis['technical']
        conditions = []
        
        # MACD信号
        if tech.get('macd_trend') == 'bearish':
            conditions.append(True)
        
        # RSI信号
        if tech.get('rsi', 30) > 30:  # RSI未超卖
            conditions.append(True)
            
        # ML信号 (如果有)
        if analysis.get('ml', {}).get('prediction') == 'down':
            conditions.append(True)
            
        # 满足大部分条件时返回True
        return len(conditions) >= 2
